package com.yuyou.fn.wx.service.impl;

import com.yuyou.fn.wx.config.WxMpInRedisConfigStorage;
import com.yuyou.fn.wx.handler.*;
import com.yuyou.fn.wx.service.IWeixinService;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * Created by wens on 2017/3/6.
 */
@Service
public class WeixinServiceImpl extends WxMpServiceImpl implements IWeixinService {

    private static final Logger log = LoggerFactory.getLogger(WeixinServiceImpl.class);

    @Resource
    protected LogHandler logHandler;

    @Resource
    protected NullHandler nullHandler;

    @Resource
    protected KfSessionHandler kfSessionHandler;

    @Resource
    private LocationHandler locationHandler;

    @Resource
    private MenuHandler menuHandler;

    @Resource
    private MsgHandler msgHandler;

    @Resource
    private UnsubscribeHandler unsubscribeHandler;

    @Resource
    private SubscribeHandler subscribeHandler;

    @Resource
    private ScanHandler scanHandler;

    private WxMpMessageRouter router;

    @Resource
    private RedisTemplate redisTemplate;

    @Value("${wx.app.id}")
    private String wxAppId;

    @Value("${wx.secret}")
    private String wxSecret;

    @Value("${wx.token}")
    private String wxToken;


    @PostConstruct
    public void init() {
        final WxMpInRedisConfigStorage config = new WxMpInRedisConfigStorage(redisTemplate);
        config.setAppId(wxAppId);// 设置微信公众号的appid
        config.setSecret(wxSecret);// 设置微信公众号的app corpSecret
        config.setToken(wxToken);// 设置微信公众号的token
        super.setWxMpConfigStorage(config);
        this.refreshRouter();

    }


    private void refreshRouter() {
        final WxMpMessageRouter newRouter = new WxMpMessageRouter(this);

        // 记录所有事件的日志
        newRouter.rule().handler(this.logHandler).next();

        // 接收客服会话管理事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT).event(WxConsts.EVT_KF_CREATE_SESSION)
                .handler(this.kfSessionHandler).end();
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT).event(WxConsts.EVT_KF_CLOSE_SESSION)
                .handler(this.kfSessionHandler).end();
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT).event(WxConsts.EVT_KF_SWITCH_SESSION)
                .handler(this.kfSessionHandler).end();


        // 自定义菜单事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
                .event(WxConsts.BUTTON_CLICK).handler(this.menuHandler).end();

        // 点击菜单连接事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
                .event(WxConsts.BUTTON_VIEW).handler(this.nullHandler).end();

        // 关注事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
                .event(WxConsts.EVT_SUBSCRIBE).handler(this.subscribeHandler)
                .end();

        // 取消关注事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
                .event(WxConsts.EVT_UNSUBSCRIBE).handler(unsubscribeHandler)
                .end();

        // 上报地理位置事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
                .event(WxConsts.EVT_LOCATION).handler(this.locationHandler).end();

        // 接收地理位置消息
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_LOCATION)
                .handler(this.locationHandler).end();

        // 扫码事件
        newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
                .event(WxConsts.EVT_SCAN).handler(this.scanHandler).end();

        // 默认
        newRouter.rule().async(false).handler(this.msgHandler).end();

        this.router = newRouter;
    }


    @Override
    public WxMpXmlOutMessage route(WxMpXmlMessage message) {

        try {
            return this.router.route(message);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }

        return null;
    }

    @Override
    public boolean hasKefuOnline() {
        try {
            WxMpKfOnlineList kfOnlineList = this.getKefuService().kfOnlineList();
            return kfOnlineList != null && kfOnlineList.getKfOnlineList().size() > 0;
        } catch (Exception e) {
            log.error("获取客服在线状态异常: " + e.getMessage(), e);
        }

        return false;
    }

}
